home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- X-UNIX-From: em@dce.ie
- organization: Datacode Communications Ltd, Dublin, Ireland
- subject: v14i094: rn patch to identify posters of articles
- from: em@dce.ie (Eamonn McManus)
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 14, Issue 94
- Submitted-by: em@dce.ie (Eamonn McManus)
- Archive-name: rn-comments/part01
-
- This patch to rn is intended to solve the problem where you are looking
- at a news article and think, "Isn't that the person who said...?" It allows
- you to have a file containing a set of entries, each of which consists of a
- person's address and an associated comment. The comment is printed out
- under the From line of any article by that person. So if someone posts
- something really stupid (or really clever) you can arrange for all their
- subsequent articles to be branded (or emblazoned) with your own personal
- prejudice against (or for) that person.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: RNPREJUDICE RNPREJ.PATCH checkfrom.c stb.c stb.h
- # Wrapped by em@dce.ie on Tue Sep 11 23:38:38 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f RNPREJUDICE -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"RNPREJUDICE\"
- else
- echo shar: Extracting \"RNPREJUDICE\" \(3995 characters\)
- sed "s/^X//" >RNPREJUDICE <<'END_OF_RNPREJUDICE'
- XABOUT RNPREJUDICE
- X
- XThe rnprejudice patch is intended to solve the problem where you are looking
- Xat a news article and think, "Isn't that the person who said...?" It allows
- Xyou to have a file containing a set of entries, each of which consists of a
- Xperson's address and an associated comment. The comment is printed out
- Xunder the From line of any article by that person. So if someone posts
- Xsomething really stupid (or really clever) you can arrange for all their
- Xsubsequent articles to be branded (or emblazoned) with your own personal
- Xprejudice against (or for) that person.
- X
- XThe modified rn looks in the RNPREJUDICE environment variable for the name
- Xof the prejudice file. You can define this variable in your login script,
- Xor via the -E option to rn.
- X
- XLines in the prejudice file beginning with # are comments. Unindented lines
- Xcontain mail addresses which are checked against the From line of each
- Xarticle. If a match is found, the indented lines following the match will
- Xbe printed. The From line must match exactly, i.e., the case of letters
- Xmust be the same. The parenthesised personal name is ignored in the match.
- X
- X# Here is an example rnprejudice file.
- Xem@dce.ie
- X Author of rnprejudice patch
- Xemcmanus@cs.tcd.ie
- X Author of rnprejudice patch
- X# If someone has multiple addresses, they must have multiple entries.
- Xquestionable@severed-head.com
- X Believes that the Earth is flat, that skyscapers are the remnants of
- X a lost civilisation, and that Reagan wasn't so bad after all.
- XBIFF@BIT.NET
- X Classic BIFF
- X
- XIn your .rnmac file you might define a macro like this:
- X# Edit the rnprejudice file
- X* !echo '%t' >>$RNPREJUDICE; vi + $RNPREJUDICE\n
- XThis appends the e-mail address from the current article to the prejudice
- Xfile and starts you up in the editor, where you can add the comment. When
- Xyou return from the edit, rn will notice that the file has been edited and
- Xread in the new copy.
- X
- X
- XAPPLYING THE PATCH
- X
- XIn the rn source directory, feed the file RNPREJ.PATCH to the patch program.
- XThis makes a small change to art.c so that it calls a function to look up
- Xthe From line of an article after displaying it, and modifies the Makefile
- Xto know about the new files checkfrom.c, stb.c, and stb.h. Because the
- Xchanges are so small, they should work with most versions of rn. The patch
- Xwas derived from version 4.3.2.2, patchlevel 44.
- X
- X"make rn" should recompile rn without problems. If the new files fail to
- Xcompile, mail me <em@dce.ie> with a description of the problem.
- X
- X
- XIMPLEMENTATION NOTES
- X
- XSince the prejudice entries are kept entirely in memory, the patched rn
- Xprobably won't run on machines with small address spaces.
- X
- XThe in-memory data are handled by the code in stb.c. This uses a binary
- Xtree for each possible initial letter. If you keep your rnprejudice file
- Xin alphabetical order, performance will be bad. A hash table might be
- Xbetter, but I wanted to avoid a big overhead when the prejudice file is
- Xsmall. (In my experience it grows pretty quickly, though.) It would be
- Xeasy to replace this file with a different implementation.
- X
- XThere are some things that could be improved:
- X* Lookups should not be case-sensitive, at least for the domain portion of
- X the address. The addresses in people's postings tend to show up with
- X consistent case however.
- X* It would be convenient if you could have different aliases for the same
- X person, rather than having to enter the same prejudice multiple times as
- X at present. Each block of unindented lines could be taken as a set of
- X addresses for the same person.
- X* It might be better to look up the name in the parenthesised comment instead
- X of or as well as the mail address.
- X* If you change the RNPREJUDICE environment variable within rn (using &-E)
- X the code does not notice. This could be fixed, but I don't see any need
- X at present.
- X
- X
- XSTATUS
- X
- XThis patch is by Eamonn McManus, Datacode Communications Ltd <em@dce.ie>.
- XIt is not copyrighted and may be used freely.
- X
- X$Id: RNPREJUDICE,v 1.1 90/09/11 23:01:34 em Exp $
- END_OF_RNPREJUDICE
- if test 3995 -ne `wc -c <RNPREJUDICE`; then
- echo shar: \"RNPREJUDICE\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f RNPREJ.PATCH -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"RNPREJ.PATCH\"
- else
- echo shar: Extracting \"RNPREJ.PATCH\" \(4738 characters\)
- sed "s/^X//" >RNPREJ.PATCH <<'END_OF_RNPREJ.PATCH'
- X*** art.c.old Thu Jan 25 20:51:50 1990
- X--- art.c Tue Sep 11 21:09:11 1990
- X***************
- X*** 193,198 ****
- X--- 193,201 ----
- X restart = Nullch; /* and reset the flag */
- X }
- X else { /* not a restart */
- X+ /* em@dce.ie: look up From in prejudice database. */
- X+ if (in_header == FROM_LINE)
- X+ linenum += checkfrom(art_buf);
- X if (fgets(art_buf,LBUFLEN,artfp)==Nullch) {
- X /* if all done */
- X mode = oldmode;
- X*** Makefile.old Sat Jan 20 18:15:38 1990
- X--- Makefile Mon Aug 13 22:32:49 1990
- X***************
- X*** 55,61 ****
- X h1 = addng.h art.h artio.h artsrch.h backpage.h bits.h cheat.h common.h
- X h2 = final.h head.h help.h init.h intrp.h kfile.h last.h ndir.h ng.h
- X h3 = ngdata.h ngsrch.h ngstuff.h only.h rcln.h rcstuff.h
- X! h4 = respond.h rn.h search.h sw.h term.h util.h
- X
- X h = $(h1) $(h2) $(h3) $(h4) $(h5)
- X
- X--- 55,61 ----
- X h1 = addng.h art.h artio.h artsrch.h backpage.h bits.h cheat.h common.h
- X h2 = final.h head.h help.h init.h intrp.h kfile.h last.h ndir.h ng.h
- X h3 = ngdata.h ngsrch.h ngstuff.h only.h rcln.h rcstuff.h
- X! h4 = respond.h rn.h search.h sw.h term.h util.h stb.h
- X
- X h = $(h1) $(h2) $(h3) $(h4) $(h5)
- X
- X***************
- X*** 62,68 ****
- X c1 = addng.c art.c artio.c artsrch.c backpage.c bits.c cheat.c
- X c2 = final.c head.c help.c init.c intrp.c kfile.c last.c $(NDIRC) ng.c
- X c3 = ngdata.c ngsrch.c ngstuff.c only.c rcln.c rcstuff.c
- X! c4 = respond.c rn.c search.c sw.c term.c util.c
- X
- X c = $(c1) $(c2) $(c3) $(c4) $(c5)
- X
- X--- 62,68 ----
- X c1 = addng.c art.c artio.c artsrch.c backpage.c bits.c cheat.c
- X c2 = final.c head.c help.c init.c intrp.c kfile.c last.c $(NDIRC) ng.c
- X c3 = ngdata.c ngsrch.c ngstuff.c only.c rcln.c rcstuff.c
- X! c4 = respond.c rn.c search.c sw.c term.c util.c checkfrom.c stb.c
- X
- X c = $(c1) $(c2) $(c3) $(c4) $(c5)
- X
- X***************
- X*** 69,75 ****
- X obj1 = addng.o art.o artio.o artsrch.o backpage.o bits.o cheat.o
- X obj2 = final.o head.o help.o init.o intrp.o kfile.o last.o $(NDIRO) ng.o
- X obj3 = ngdata.o ngsrch.o ngstuff.o only.o rcln.o rcstuff.o
- X! obj4 = respond.o rn.o search.o sw.o term.o util.o
- X
- X obj = $(obj1) $(obj2) $(obj3) $(obj4) $(obj5)
- X
- X--- 69,75 ----
- X obj1 = addng.o art.o artio.o artsrch.o backpage.o bits.o cheat.o
- X obj2 = final.o head.o help.o init.o intrp.o kfile.o last.o $(NDIRO) ng.o
- X obj3 = ngdata.o ngsrch.o ngstuff.o only.o rcln.o rcstuff.o
- X! obj4 = respond.o rn.o search.o sw.o term.o util.o checkfrom.o stb.o
- X
- X obj = $(obj1) $(obj2) $(obj3) $(obj4) $(obj5)
- X
- X*** Makefile.SH.old Sat Jan 20 17:57:51 1990
- X--- Makefile.SH Mon Aug 13 16:26:13 1990
- X***************
- X*** 64,70 ****
- X h1 = addng.h art.h artio.h artsrch.h backpage.h bits.h cheat.h common.h
- X h2 = final.h head.h help.h init.h intrp.h kfile.h last.h ndir.h ng.h
- X h3 = ngdata.h ngsrch.h ngstuff.h only.h rcln.h rcstuff.h
- X! h4 = respond.h rn.h search.h sw.h term.h util.h
- X #NNTPh5 = server.h
- X
- X h = $(h1) $(h2) $(h3) $(h4) $(h5)
- X--- 64,70 ----
- X h1 = addng.h art.h artio.h artsrch.h backpage.h bits.h cheat.h common.h
- X h2 = final.h head.h help.h init.h intrp.h kfile.h last.h ndir.h ng.h
- X h3 = ngdata.h ngsrch.h ngstuff.h only.h rcln.h rcstuff.h
- X! h4 = respond.h rn.h search.h sw.h term.h util.h stb.h
- X #NNTPh5 = server.h
- X
- X h = $(h1) $(h2) $(h3) $(h4) $(h5)
- X***************
- X*** 72,78 ****
- X c1 = addng.c art.c artio.c artsrch.c backpage.c bits.c cheat.c
- X c2 = final.c head.c help.c init.c intrp.c kfile.c last.c $(NDIRC) ng.c
- X c3 = ngdata.c ngsrch.c ngstuff.c only.c rcln.c rcstuff.c
- X! c4 = respond.c rn.c search.c sw.c term.c util.c
- X #NNTPc5 = $(NNTPDIR)/common/clientlib.c
- X
- X c = $(c1) $(c2) $(c3) $(c4) $(c5)
- X--- 72,78 ----
- X c1 = addng.c art.c artio.c artsrch.c backpage.c bits.c cheat.c
- X c2 = final.c head.c help.c init.c intrp.c kfile.c last.c $(NDIRC) ng.c
- X c3 = ngdata.c ngsrch.c ngstuff.c only.c rcln.c rcstuff.c
- X! c4 = respond.c rn.c search.c sw.c term.c util.c checkfrom.c stb.c
- X #NNTPc5 = $(NNTPDIR)/common/clientlib.c
- X
- X c = $(c1) $(c2) $(c3) $(c4) $(c5)
- X***************
- X*** 80,86 ****
- X obj1 = addng.o art.o artio.o artsrch.o backpage.o bits.o cheat.o
- X obj2 = final.o head.o help.o init.o intrp.o kfile.o last.o $(NDIRO) ng.o
- X obj3 = ngdata.o ngsrch.o ngstuff.o only.o rcln.o rcstuff.o
- X! obj4 = respond.o rn.o search.o sw.o term.o util.o
- X #NNTPobj5 = $(NNTPDIR)/common/clientlib.o
- X
- X obj = $(obj1) $(obj2) $(obj3) $(obj4) $(obj5)
- X--- 80,86 ----
- X obj1 = addng.o art.o artio.o artsrch.o backpage.o bits.o cheat.o
- X obj2 = final.o head.o help.o init.o intrp.o kfile.o last.o $(NDIRO) ng.o
- X obj3 = ngdata.o ngsrch.o ngstuff.o only.o rcln.o rcstuff.o
- X! obj4 = respond.o rn.o search.o sw.o term.o util.o checkfrom.o stb.o
- X #NNTPobj5 = $(NNTPDIR)/common/clientlib.o
- X
- X obj = $(obj1) $(obj2) $(obj3) $(obj4) $(obj5)
- END_OF_RNPREJ.PATCH
- if test 4738 -ne `wc -c <RNPREJ.PATCH`; then
- echo shar: \"RNPREJ.PATCH\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f checkfrom.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"checkfrom.c\"
- else
- echo shar: Extracting \"checkfrom.c\" \(4004 characters\)
- sed "s/^X//" >checkfrom.c <<'END_OF_checkfrom.c'
- X/* checkfrom.c - print information about news article originator. */
- X
- X/* By Eamonn McManus, <em@dce.ie>. This file is not copyrighted.
- X * $Id: checkfrom.c,v 1.2 90/09/11 23:37:39 em Exp $
- X *
- X * This file contains the checkfrom() function, invoked from (modified) rn
- X * after a From: header line to see if the person named is mentioned in the
- X * RNPREJUDICE file. If so, the text for that person is printed, and the
- X * number of lines that were printed is returned. If not, 0 is returned.
- X *
- X * Each key in the file is on a line of its own,
- X * followed by zero or more data lines starting with whitespace. Lines
- X * beginning with # are comments, as are leading indented lines.
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "config.h"
- X#ifdef __STDC__
- X#include <stdlib.h>
- X#include <string.h>
- X#undef index
- X#define index strchr
- X#else
- Xextern char *malloc();
- Xextern void free();
- Xextern char *getenv();
- Xextern char *index();
- X#endif
- X
- Xtypedef char *datum;
- X#include "stb.h"
- X
- X
- Xextern char *savestr ARGS((char *str));
- X
- Xstatic stb *db;
- X
- X
- X/* Read the file into memory. Return the number of keys read, or -1 on error.
- X */
- Xstatic int read_file(f)
- Xregister FILE *f;
- X{
- X register int c, i;
- X int nkeys;
- X char key[1024]; /* Hardcoded limits; tough. */
- X char data[4096], *datacopy;
- X if (db == NULL && (db = stb_new_table()) == NULL)
- X return -1;
- X nkeys = 0;
- X /* Each iteration reads a key and following data. */
- X while ((c = getc(f)) != EOF) {
- X /* Get the key. */
- X for (i = 0; i < sizeof key - 1 && c != '\n'; c = getc(f)) {
- X if (c == EOF)
- X return nkeys;
- X key[i++] = c;
- X }
- X if (i == 0 || key[0] == '#' || isspace(key[0]))
- X continue;
- X key[i] = '\0';
- X /* Get the data. */
- X i = 0;
- X /* Read the indented lines. */
- X while (isspace(c = getc(f))) {
- X /* Read a line. */
- X while (1) {
- X if (c == EOF)
- X return nkeys;
- X if (i < sizeof data - 1)
- X data[i++] = c;
- X if (c == '\n')
- X break;
- X c = getc(f);
- X }
- X }
- X (void) ungetc(c, f);
- X data[i] = '\0';
- X datacopy = savestr(data);
- X if (stb_insert(db, key, &datacopy) == NULL) {
- X free(datacopy);
- X } else nkeys++;
- X }
- X return nkeys;
- X}
- X
- X
- X/* Action function for stb_free_tree. */
- Xstatic int sfree(p)
- Xchar *p;
- X{
- X free(p);
- X return 0;
- X}
- X
- X
- X/* See if the electronic address in the fromline appears in the prejudice
- X * database. If so, print the indented lines that follow. Return the
- X * number of lines printed. The string pointed to by fromline is modified.
- X */
- Xint checkfrom(fromline)
- Xregister char *fromline;
- X{
- X register char *p, *dbname;
- X register stb_node *s;
- X int lines, t;
- X static char beenhere;
- X static FILE *f;
- X static time_t mtime;
- X struct stat st;
- X /* Slurp in the database if we haven't already, or if it has been
- X * modified since we read it.
- X */
- X if (beenhere) {
- X if (f == NULL)
- X return 0;
- X if ((t = fstat(fileno(f), &st)) < 0 || st.st_mtime > mtime) {
- X (void) stb_free_table(db, sfree); db = NULL;
- X if (t < 0) {
- X fclose(f); f = NULL;
- X return 0;
- X } else {
- X rewind(f);
- X mtime = st.st_mtime;
- X beenhere = 0;
- X }
- X }
- X } else {
- X if ((dbname = getenv("RNPREJUDICE")) == NULL)
- X return 0;
- X if ((f = fopen(dbname, "r")) == NULL ||
- X fstat(fileno(f), &st) < 0) {
- X printf("[Could not open RNPREJUDICE=\"%s\"]\n", dbname);
- X f = NULL;
- X return 1;
- X }
- X mtime = st.st_mtime;
- X }
- X if (!beenhere) {
- X beenhere++;
- X if (read_file(f) < 0) {
- X printf("[Format error in $RNPREJUDICE]\n");
- X fclose(f); f = NULL;
- X return 1;
- X }
- X }
- X /* Isolate the address part of the from line. Skip the initial
- X * "From:" as well as any trailing stuff (usually the personal
- X * name comment).
- X */
- X for ( ; *fromline && !isspace(*fromline); fromline++) ;
- X for ( ; isspace(*fromline); fromline++) ;
- X for (p = fromline; *p && !isspace(*p); p++) ;
- X if (p == fromline)
- X return 0;
- X *p = '\0';
- X if ((s = stb_lookup(db, fromline)) == NULL)
- X return 0;
- X fputs(s->datum, stdout);
- X for (lines = 0, p = s->datum; (p = index(p, '\n')) != NULL;
- X lines++, p++) ;
- X return lines;
- X}
- END_OF_checkfrom.c
- if test 4004 -ne `wc -c <checkfrom.c`; then
- echo shar: \"checkfrom.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f stb.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"stb.c\"
- else
- echo shar: Extracting \"stb.c\" \(6095 characters\)
- sed "s/^X//" >stb.c <<'END_OF_stb.c'
- X/* stb.c - symbol table functions */
- X
- X/* By Eamonn McManus <em@dce.ie>. This file is not copyrighted.
- X * $Id: stb.c,v 1.2 90/09/11 23:37:49 em Exp $
- X *
- X * Functions using a simple binary forest to implement symbol table
- X * operations. Should be recompiled with DATUM defined on the command
- X * line as a declaration for variable datum of suitable type. Default
- X * is equivalent to -DDATUM="char *datum".
- X */
- X
- X#ifndef DATUM
- X#define DATUM char *datum
- X#endif
- X
- Xtypedef DATUM;
- X
- X#include "stb.h"
- X#ifdef __STDC__
- X#include <string.h> /* For strcpy(). */
- X#include <stdlib.h>
- X#else
- Xextern char *malloc();
- Xextern char *strcpy();
- Xextern void free();
- X#endif
- X
- X#ifndef NULL
- X# define NULL 0
- X#endif
- X
- X
- X/* Return a new symbol table. NULL if can't make one. */
- Xstb *stb_new_table()
- X{
- X /* Note that calloc() to get an array of NULLs is not portable. */
- X register int i;
- X register stb *s = (stb *) malloc(sizeof(stb));
- X for (i = 0; i < MAXCHAR; i++)
- X (*s)[i] = NULL;
- X return s;
- X}
- X
- X
- X/* Free tree rooted at root, using function datumfree. */
- Xstatic int free_tree(root, datumfree)
- Xregister stb_node *root;
- Xregister int (*datumfree)();
- X{
- X register stb_node *n;
- X for ( ; root != NULL; root = n) {
- X if (free_tree(root->link[0], datumfree) < 0)
- X return -1;
- X n = root->link[1];
- X if ((*datumfree)(root->datum) < 0)
- X return -1;
- X free((char *) root->name);
- X free((char *) root);
- X }
- X return 0;
- X}
- X
- X
- X/* Free a symbol table. Return 0 if OK, -1 if error. Datumfree is a
- X * routine to free the datum in each node, returning the same error status.
- X */
- Xint stb_free_table(table, datumfree)
- Xregister stb *table;
- Xregister int (*datumfree)();
- X{
- X register int i;
- X for (i = 0; i < MAXCHAR; i++)
- X if (free_tree((*table)[i], datumfree) < 0)
- X return -1;
- X free((char *) table);
- X return 0;
- X}
- X
- X
- X/* Look up a symbol. Return pointer to its node or NULL if not found. */
- Xstb_node *stb_lookup(table, name)
- Xstb *table;
- Xregister char *name;
- X{
- X register stb_node *n;
- X register int order;
- X if (name[0] == '\0')
- X return (*table)['\0']; /* Only one null symbol. */
- X if ((unsigned char) name[0] >= MAXCHAR)
- X return NULL; /* Invalid. */
- X for (n = (*table)[(unsigned char) *name++]; n; n = n->link[order > 0])
- X if ((order = strcmp(name, n->name + 1)) == 0)
- X return n;
- X return NULL;
- X}
- X
- X
- X/* Insert a symbol. Returns the inserted node, or NULL if there was an
- X * error or the symbol was already present.
- X */
- Xstb_node *stb_insert(table, name, newdatum)
- Xstb *table;
- Xregister char *name;
- Xdatum *newdatum;
- X{
- X register stb_node *parent, *n, **link;
- X register int order;
- X register char *namecpy;
- X if ((unsigned char) *name >= MAXCHAR)
- X return NULL; /* Invalid. */
- X parent = NULL;
- X link = *table + (unsigned char) name[0];
- X n = *link;
- X if (*name++) { /* Only one null symbol, no search. */
- X while (n != NULL) {
- X if ((order = strcmp(name, n->name + 1)) == 0)
- X break;
- X link = &n->link[order > 0];
- X parent = n; n = *link;
- X }
- X }
- X if (n != NULL)
- X return NULL; /* Already present. */
- X if ((namecpy = malloc((unsigned) strlen(--name) + 1)) == NULL)
- X return NULL; /* Out of memory. */
- X (void) strcpy(namecpy, name);
- X if ((n = (stb_node *) malloc(sizeof(stb_node))) == NULL)
- X return NULL;
- X n->link[0] = n->link[1] = NULL;
- X n->parent = parent; n->name = namecpy; n->datum = *newdatum;
- X *link = n;
- X return n;
- X}
- X
- X
- X/* Subsequent functions are not used in the rnprejudice code. */
- X#ifdef UNPREJUDICED
- X
- X/* Return lowest valued descendant of node. */
- Xstatic stb_node *first(node)
- Xregister stb_node *node;
- X{
- X while (node->link[0] != NULL)
- X node = node->link[0];
- X return node;
- X}
- X
- X
- X/* Return first symbol in table, NULL if table is empty. */
- Xstb_node *stb_first(table)
- Xregister stb *table;
- X{
- X register int i;
- X for (i = 0; i < MAXCHAR; i++)
- X if ((*table)[i] != NULL)
- X return first((*table)[i]);
- X return NULL;
- X}
- X
- X
- X/* Return the next symbol after the given node, NULL if none. */
- Xstb_node *stb_next(table, node)
- Xstb *table;
- Xregister stb_node *node;
- X{
- X register int i;
- X /* If there is a right pointer, return its smallest descendant.
- X * If this is the left descendant of a node, return that node.
- X * Otherwise, we want that node's next.
- X */
- X if (node->link[1] != NULL)
- X return first(node->link[1]);
- X for ( ; node->parent != NULL; node = node->parent)
- X if (node->parent->link[0] == node)
- X return node->parent;
- X /* At root for this initial char. Find next tree. */
- X for (i = node->name[0] + 1; i < MAXCHAR; i++)
- X if ((*table)[i])
- X return first((*table)[i]);
- X return NULL;
- X}
- X
- X
- X/* Delete a node. Return 0 if OK, else -1. Datumfree is a function to
- X * free the datum part of the node, returning the same kind of status.
- X */
- Xint stb_delete(table, node, datumfree)
- Xstb *table;
- Xregister stb_node *node;
- Xint (*datumfree)();
- X{
- X register stb_node **link, *succ;
- X /* Find the link from the parent that we want to change. */
- X if (node->parent == NULL)
- X link = *table + node->name[0]; /* In the array of roots. */
- X else link = &node->parent->link[node->parent->link[1] == node];
- X /* If either descendant is NULL, replace with the other. Otherwise
- X * find the successor and replace with that.
- X */
- X if (node->link[0] == NULL)
- X *link = node->link[1];
- X else if (node->link[1] == NULL)
- X *link = node->link[0];
- X else {
- X succ = first(node->link[1]);
- X /* Replace the deleted node with its successor, succ. Succ
- X * has no left child (since that would be the successor), so
- X * it inherits the original node's left child.
- X * If succ is the right child of the original node, that is
- X * enough. Otherwise, succ's parent
- X * inherits succ's right child as its left child (which was
- X * succ), and succ inherits the original node's right child.
- X */
- X succ->link[0] = node->link[0]; node->link[0]->parent = succ;
- X if (succ->parent != node) {
- X succ->parent->link[0] = succ->link[1];
- X if (succ->link[1] != NULL)
- X succ->link[1]->parent = succ->parent;
- X succ->link[1] = node->link[1];
- X node->link[1]->parent = succ;
- X }
- X *link = succ;
- X }
- X if (*link != NULL)
- X (*link)->parent = node->parent;
- X if ((*datumfree)(node->datum) < 0)
- X return -1;
- X free((char *)node->name); free((char *)node);
- X return 0;
- X}
- X
- X#endif /* UNPREJUDICED */
- END_OF_stb.c
- if test 6095 -ne `wc -c <stb.c`; then
- echo shar: \"stb.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f stb.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"stb.h\"
- else
- echo shar: Extracting \"stb.h\" \(871 characters\)
- sed "s/^X//" >stb.h <<'END_OF_stb.h'
- X/* stb.h - declarations for symbol-table package stb.c. */
- X
- X/* By Eamonn McManus <em@dce.ie>. This file is not copyrighted.
- X * $Id: stb.h,v 1.2 90/09/11 23:38:07 em Exp $
- X */
- X
- X#ifndef MAXCHAR
- X# define MAXCHAR 256
- X#endif
- X
- Xtypedef struct stb_node {
- X struct stb_node *link[2], *parent;
- X char *name;
- X datum datum; /* datum must be typedef'd first. */
- X} stb_node;
- X
- Xtypedef stb_node *stb[MAXCHAR];
- X
- X#ifndef ARGS
- X# ifndef __STDC__
- X# define ARGS(x) ()
- X# else
- X# define ARGS(x) x
- X# endif
- X#endif
- X
- Xstb *stb_new_table ARGS((void));
- Xint stb_free_table ARGS((stb *table, int (*datumfree)()));
- Xstb_node *stb_lookup ARGS((stb *table, char *name));
- Xstb_node *stb_insert ARGS((stb *table, char *name, datum *newdatum));
- Xstb_node *stb_first ARGS((stb *table));
- Xstb_node *stb_next ARGS((stb *table, stb_node *node));
- Xint stb_delete ARGS((stb *table, stb_node *node, int (*datumfree)()));
- END_OF_stb.h
- if test 871 -ne `wc -c <stb.h`; then
- echo shar: \"stb.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-
-